package com.maxatime.service.impl;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.maxatime.dao.WeatherMapper;
import com.maxatime.exception.PenguinException;
import com.maxatime.manage.juhe.SimpleWeather;
import com.maxatime.pojo.entity.Weather;
import com.maxatime.service.WeatherService;
import com.maxatime.util.PenguinDateTimeUtils;
import com.maxatime.util.WeatherContent;

@Service
public class WeatherServiceImpl implements WeatherService{
	
	@Autowired
	WeatherMapper weatherMapper;
	
	// 日志
		Logger log = LogManager.getLogger();


		@Override
		public String getCityNameByLongitudeAndLatitude(String longitude, String latitude) {
			// TODO Auto-generated method stub

			// 调用第三方接口
			String str = queryInfoByLonLat(longitude, latitude);
			log.info("高德API返回数据::: " + str);

			JSONObject jsonObj = JSONObject.parseObject(str);
			String status = jsonObj.getString("status");
			if (!status.equals("1")) {
				// 错误情况
			}

			// regeocode
			JSONObject regeocode = jsonObj.getJSONObject("regeocode");

			JSONObject addressComponent = regeocode.getJSONObject("addressComponent");

			// 获取城市， 他是个数组
			JSONArray cityArray = addressComponent.getJSONArray("city");
			String city = "";
			if (cityArray.size() > 0) {
				city = cityArray.getString(0);
			} else {
				city = addressComponent.getString("province");
				log.info("根据经纬度查询到的省:接口返回:: " + city);
			}
			log.info("根据经纬度查询到的城市:接口返回:: " + city);

			// 直辖市，city为空
			// 请注意：当城市是省直辖县时返回为空，以及城市为北京、上海、天津、重庆四个直辖市时，该字段返回为空
			String cityok = lastCharacter(city);
			log.info("根据经纬度查询到的城市::: " + cityok);
			return cityok;
		}

		/**
		 * @Description: 删除字符串最后一个字符
		 * @param: @param  province
		 * @param: @return
		 * @return: String
		 * @throws
		 * @author: zero
		 * @date: 2023年3月21日 下午6:31:27
		 * @version V1.0
		 */
		private String lastCharacter(String province) {
			// 只做省，直辖市处理
			String city = province.substring(0, province.length() - 1);
			return city;
		}

		// fa8381f88f95ac149df22264572d9c3d
		// 經緯度-》城市
		// https://restapi.amap.com/v3/geocode/regeo?output=xml&location=116.310003,39.991957&key=<用户的key>&radius=1000&extensions=all
		// 城市 -》 經緯度
		// https://restapi.amap.com/v3/geocode/geo?address=北京市朝阳区阜通东大街6号&output=XML&key=<用户的key>
		// 文档 https://lbs.amap.com/api/webservice/guide/api/georegeo/
		//
		private String queryInfoByLonLat(String longitude, String latitude) {
			// TODO Auto-generated method stub

			String resutlt = null;
			// 建立一个HttpClient实例
			CloseableHttpClient httpClient = null;
			try {
				httpClient = HttpClients.createDefault();
				// 装填参数
				List<NameValuePair> params = new ArrayList<NameValuePair>();
				// params.add(new BasicNameValuePair("location", "116.3100,39.9919")); //字符串参数
				params.add(new BasicNameValuePair("location", longitude + "," + latitude)); // 字符串参数
				params.add(new BasicNameValuePair("key", "39bca60e14f4cec5faffd0842f54941b")); // 字符串参数
				params.add(new BasicNameValuePair("radius", "1000")); // 字符串参数
				params.add(new BasicNameValuePair("extensions", "all")); // 字符串参数
				// 转换为键值对
				String str = EntityUtils.toString(new UrlEncodedFormEntity(params, Consts.UTF_8));
				// 建立一个HttpGet实例
				HttpGet httpGet = new HttpGet("https://restapi.amap.com/v3/geocode/regeo?" + str);
				// 发送GET请求
				HttpResponse execute = httpClient.execute(httpGet);
				// 获取状态码
				int statusCode = execute.getStatusLine().getStatusCode();
				System.out.println(statusCode);
				HttpEntity entity = execute.getEntity();
				resutlt = EntityUtils.toString(entity, "utf-8");
				System.out.println("===========" + resutlt);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (httpClient != null) {
					try {
						httpClient.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
			return resutlt;
		}
		
		//根据城市查天气
		@Transactional
		@Override
		public Map<String, Object> getWeatherByCityName(String city) throws PenguinException {
			// TODO Auto-generated method stub
			// 返回值
			Map<String, Object> m = new HashMap<String, Object>();

			log.info("城市名称： " + city);

			// 判断参数
			String cityName = StringUtils.trimToNull(city);
			if (cityName == null) {
				return m;
			}
			// 查询数据库
			log.info("城市名称-cityName: " + cityName);
			List<Weather> list = null;
			try {
				Weather weather = new Weather();
				weather.setCity(cityName);
				weather.setDeleteFlag("0");
				log.info("天气查询-weatherMapper.queryWeatherByCity-req: " + weather);
				list = weatherMapper.queryWeatherByCity(weather);
				log.info("天气查询-weatherMapper.queryWeatherByCity-resp: " + list);
			} catch (Exception e) {
				throw new PenguinException(e.getMessage());
			} catch (Throwable te) {
				throw new PenguinException(te.getMessage());
			}

			// 判断是否有数据
			if (list.size() == 0) {
				// 查询天气接口 保存到数据库
				Map<String, Object> mQw = queryWeatherSaveDb(cityName);
				log.info("表里没有数据查询接口-queryWeatherSaveDb: " + mQw);
				// 返回
				return mQw;
			}

			// 有数据
			Weather weather = list.get(0);
			// 计算时间
			LocalDateTime ldt1 = LocalDateTime.now();
			LocalDateTime ldt2 = PenguinDateTimeUtils.dateConverLocalDateTime(weather.getCreateTime());
			log.info("当前系统时间::: " + ldt1);
			log.info("天气上次查询时间::: " + ldt2);
			long lHour = PenguinDateTimeUtils.getHoursBetween(ldt2, ldt1);
			log.info("查询天气两次时间间隔::: " + lHour);
			// 判断数据时间是否超过4小时
			if (lHour > 4) {
				// 查询天气接口 保存到数据库
				Map<String, Object> mQw = queryWeatherSaveDb(cityName);
				// 返回
				log.info("数据大于4小时-queryWeatherSaveDb: " + mQw);
				return mQw;
			}

			// 返回结果集 json
			m.put(WeatherContent.WEATHER_RESULT_DATA, weather.getWeatherInfo());
			log.info("getWeatherByCityName接口返回数据: " + m);
			return m;
		}
		
		// 查询天气
		private Map<String, Object> queryWeatherSaveDb(String cityName) throws PenguinException {

			// 调用聚合API
			// 判断 cityName是否末尾包含市，县
			String city = "";
			if (cityName.length() > 2) {
				String s = cityName.substring(cityName.length() - 1, cityName.length());
				if (s.equals("市") == true || s.equals("县") == true) {
					city = cityName.substring(0, cityName.length() - 1);
				} else {
					city = cityName;
				}
			} else {
				city = cityName;
			}

			log.info("SimpleWeather.queryWeatherByCity天气接口请求数据::: " + city);
			Map<String, Object> m = SimpleWeather.queryWeatherByCity(city);
			log.info("天气接口返回数据::: " + m);
			if (m == null) {
				return m;
			}

			// 保存数据库
			Weather weather = new Weather();
			weather.setCity(cityName);
			weather.setDeleteFlag("0");
			Date ldt = new Date();
			weather.setCreateTime(ldt);
			weather.setUpdateTime(ldt);
			weather.setWeatherInfo(m.get(WeatherContent.WEATHER_RESULT_DATA).toString());

			try {
				log.info("天气插入数据库::: " + weather);
				weatherMapper.insertSelective(weather);
			} catch (Exception e) {
				throw new PenguinException(e.getMessage());
			}
			return m;
		}
		//反显天气

		@Override
		public List<Weather> finddata(Weather weather) {
			// TODO Auto-generated method stub
			return weatherMapper.queryWeatherByCity(weather);
		}
		

}
